<?php

class NCore_SQLActionGateway extends NCore_SQLAction
{
	private $insertQuery 	= 'INSERT INTO {table_name} ({insert_fields}) VALUES ({insert_values})';
	private $updateQuery 	= 'UPDATE {table_name} SET {update_values} WHERE id = :id';
	private $deleteQuery 	= 'DELETE FROM {table_name} WHERE id = :id';

	function __construct($name)
	{
		parent::__construct($name);
	}
	protected function prepareUpdateValues($row)
	{
		$keyUpdateStrings = array();

		foreach($row as $key=>$value)
		{
			if($key == 'id') continue;
			$keyUpdateStrings[] = $key.' = :'.$key;
		}

		return implode(', ', $keyUpdateStrings); 
	}
	protected function prepareInsertFields($row)
	{
		$insertFields = array();
		foreach($row as $key=>$value)
		{
			$insertFields[] = $key;
		}
		return implode(', ', $insertFields);
	}
	protected function prepareInsertValues($row)
	{
		$insertValues = array();
		foreach($row as $key=>$value)
		{
			$insertValues[] = ':'.$key;
		}
		return implode(', ', $insertValues);
	}
	public function delete($id)
	{
		$dbh = $this->getConnection();

		$stmt = $dbh->prepare(str_replace('{table_name}', $this->getName(), $this->deleteQuery));
		$stmt->bindParam(':id', $id);

		if(!$stmt->execute())
		{
			throw new Exception('The delete action of the NCore_SQLActionGateway \''.$this->getName().'\' could not be completed.');
		}

		$dbh = NULL;
	}
	protected function update($row)
	{
		$updateValues = $this->prepareUpdateValues($row);
		
		$paramArray = array();
		
		foreach($row as $key=>$value)
		{
			$paramArray[':'.$key] = $this->getValue($value);
		}

		$dbh = $this->getConnection();

		$query = str_replace('{table_name}', $this->getName(), $this->updateQuery);
		$query = str_replace('{update_values}', $updateValues, $query);

		$stmt = $dbh->prepare($query);

		if(!$stmt->execute($paramArray))
		{
			throw new Exception('The update query in the NCore_SQLActionGateway \''.$this->getName().'\' could not be completed.');
		}

		$dbh = NULL;
	}
	protected function insert($row)
	{
		$insertFields = $this->prepareInsertFields($row);
		$insertValues = $this->prepareInsertValues($row);

		$query = str_replace('{table_name}', $this->getName(), $this->insertQuery);
		$query = str_replace('{insert_fields}', $insertFields, $query);
		$query = str_replace('{insert_values}', $insertValues, $query);
		
		$paramArray = array();
		
		foreach($row as $key=>$value)
		{
            $paramArray[':'.$key] = $this->getValue($value);
		}

		$dbh = $this->getConnection();

		$stmt = $dbh->prepare($query);
		
		if(!$stmt->execute($paramArray))
		{
			throw new Exception('The update query in the instance of NCore_SQLActionGateway could not be completed.');
		}

		$row['id'] = $dbh->lastInsertId();

		$dbh = NULL;	
	}
	public function save(NCore_Row $row)
	{		
		if(isset($row['id']))
		{
			return $this->update($row);
		}
		else
		{
			return $this->insert($row);
		}
	}
	public function run()
	{
		throw new Exception('The NCore_SQLActionGateway does not implement the run() method, but rather uses the save() or delete() methods.');
	}
    public function getValue($value)
    {
        if($value instanceof NCore_IValue)
        {
            return $value->getValue();
        }
        else
        {
            return $value;
        }
    }
}

?>